#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright (C) 1994  Ling Li
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


import gobject, gtk
from gtk import *
import logging, os, string

from coralftp_globals import *
from config import VALUE_STRING, VALUE_INT, VALUE_BOOL
from utils import *

CONFIG_FILE = os.path.join(USERDATADIR, 'config')
CONFIG_PREFIX = '/apps/coralftp'
CONFIG_NAMES = {
    'general' : {
    'email_address' :              (VALUE_STRING, Entry,
                                    'entry_email_address'),
    'default_download_path' :      (VALUE_STRING, Entry,
                                    'entry_default_download_path'),
    'status_log_filename' :        (VALUE_STRING, Entry,
                                    'entry_status_log_filename'),
    'enable_disk_based_logging' :  (VALUE_BOOL, CheckButton,
                                    'cb_enable_disk_based_logging'),
    'trim_status_log_file' :       (VALUE_BOOL, CheckButton,
                                    'cb_trim_status_log_file'),
    'status_log_file_size' :       (VALUE_INT, Entry,
                                    'spbtn_status_log_file_size'),
    'connect_timeout' :            (VALUE_INT, Entry,
                                    'spbtn_connect_timeout'),
    'connect_retry_delay' :        (VALUE_INT, Entry,
                                    'spbtn_connect_retry_delay'),
    'scrollback_buffer' :          (VALUE_INT, Entry,
                                    'spbtn_scrollback_buffer'),
    'connect_retry_count' :        (VALUE_INT, Entry,
                                    'spbtn_connect_retry_count'),
    'send_keep_alive_command' :    (VALUE_BOOL, CheckButton,
                                    'cb_send_keep_alive'),
    'keep_alive_command' :         (VALUE_STRING, Entry,
                                    'entry_keep_alive_command'),
    'send_keep_alive_interval' :   (VALUE_INT, Entry,
                                    'spbtn_send_keep_alive_interval'),
    'stop_send_keep_alive' :       (VALUE_BOOL, CheckButton,
                                    'cb_stop_send_keep_alive'),
    'stop_keep_alive_after' :      (VALUE_INT, Entry,
                                    'spbtn_stop_keep_alive_after')
    },
    'display' : {
    'display_site_name_in_caption':(VALUE_BOOL, CheckButton,
                                    'cb_display_site_name_in_caption'),
    'auto_size_file_list_columns': (VALUE_BOOL, CheckButton,
                                    'cb_auto_size_file_list_columns'),
    'auto_size_queue_list_columns':(VALUE_BOOL, CheckButton,
                                    'cb_auto_size_queue_list_columns'),
    'show_site_idle_time' :        (VALUE_BOOL, CheckButton,
                                    'cb_show_site_idle_time'),
    'start_with_site_manager' :    (VALUE_BOOL, CheckButton,
                                    'cb_start_with_site_manager'),
    'sort_folder_on_top' :         (VALUE_BOOL, CheckButton,
                                    'cb_sort_folder_on_top'),
    'rules_hint' :                 (VALUE_BOOL, CheckButton,
                                    'cb_rules_hint'),
    'ftp_sort_by' :                (VALUE_INT, RadioButton,
                                    ('radio_ftp_sort_by_name',
                                     'radio_ftp_sort_by_owner',
                                     'radio_ftp_sort_by_size',
                                     'radio_ftp_sort_by_group',
                                     'radio_ftp_sort_by_date',
                                     'radio_ftp_sort_by_file_extension')),
    'ftp_order' :                  (VALUE_INT, RadioButton,
                                    ('radio_ftp_sort_by_ascending',
                                     'radio_ftp_sort_by_descending')),
    'local_sort_by' :              (VALUE_INT, RadioButton,
                                    ('radio_local_sort_by_name',
                                     'radio_local_sort_by_type',
                                     'radio_local_sort_by_size',
                                     'radio_local_sort_by_date')),
    'local_order' :                (VALUE_INT, RadioButton,
                                    ('radio_local_sort_by_ascending',
                                     'radio_local_sort_by_descending')),
    'display_file_size_as' :       (VALUE_STRING, ComboBoxEntry,
                                    'cmbentry_display_file_size_as',
                                    ('OnlyInList','NoFocus')),
    }
    }

COLOR_FONT_CONFIG_NAMES = {
    'display' : {
    'active_side_indicator_color' : (VALUE_STRING, ColorButton,
                                     'cbtn_active_side_indicator'),
    'command_text_color' :          (VALUE_STRING, ColorButton,
                                     'cbtn_command_text'),
    'left_ftp_reply_color' :        (VALUE_STRING, ColorButton,
                                     'cbtn_left_ftp_reply_text'),
    'right_ftp_reply_color' :       (VALUE_STRING, ColorButton,
                                     'cbtn_right_ftp_reply_text'),
    'error_text_color' :            (VALUE_STRING, ColorButton,
                                     'cbtn_error_text'),
    'misc_text_color' :             (VALUE_STRING, ColorButton,
                                     'cbtn_misc_text'),
    'queue_complete_text_color' :   (VALUE_STRING, ColorButton,
                                     'cbtn_queue_complete_text'),
    'background_color' :            (VALUE_STRING, ColorButton,
                                     'cbtn_background'),
    'use_custom_file_listing_font' :(VALUE_BOOL, CheckButton,
                                     'cb_file_listing'),
    'file_listing_font' :           (VALUE_STRING, FontButton,
                                     'fbtn_file_listing'),
    'use_custom_status_font' :      (VALUE_BOOL, CheckButton,
                                     'cb_status'),
    'status_font' :                 (VALUE_STRING, FontButton,
                                     'fbtn_status'),
    'use_custom_queue_font' :       (VALUE_BOOL, CheckButton,
                                     'cb_queue'),
    'queue_font' :                  (VALUE_STRING, FontButton,
                                     'fbtn_queue'),
    }
    }

def config_value(config, group, keyname):
    if CONFIG_NAMES[group].has_key(keyname):
        setting = CONFIG_NAMES[group][keyname]
    else:
        setting = COLOR_FONT_CONFIG_NAMES[group][keyname]
    if setting[0] == VALUE_STRING:
        return config.get_string(group, keyname)
    elif setting[0] == VALUE_INT:
        return config.get_int(group, keyname)
    elif setting[0] == VALUE_BOOL:
        return config.get_bool(group, keyname)
    
def config_to_widgets(config_prefix, config_names, config, xml):
    """Load settings from config database."""
    for group, settings in config_names.items():
        for keyname, setting in settings.items():
            if setting[0] == VALUE_STRING:
                value = config.get_string(group, keyname)
            elif setting[0] == VALUE_INT:
                value = config.get_int(group, keyname)
            elif setting[0] == VALUE_BOOL:
                value = config.get_bool(group, keyname)
            else:
                raise ValueError

            if setting[1] == RadioButton:
                widget = xml.get_widget(setting[2][value])
                widget.set_property('active', True)
            elif setting[1] == Entry:
                widget = xml.get_widget(setting[2])
                widget.set_property('text', value)
            elif setting[1] == ComboBoxEntry:
                widget = xml.get_widget(setting[2])
                model = widget.get_model()
                iter = model.get_iter_first()
                while iter:
                    if value == model.get_path(iter).__str__():
                        break
                    iter = model.iter_next(iter)
                if iter != None:
                    widget.set_active_iter(iter)
                if 'OnlyInList' in setting[3]:
                    widget.child.set_property('editable', False)
                if 'NoFocus' in setting[3]:
                    widget.child.set_property('can-focus', False)
            elif setting[1] == CheckButton:
                widget = xml.get_widget(setting[2])
                widget.set_property('active', value)
            elif setting[1] == ColorButton:
                if value == None: value = '#000000'
                widget = xml.get_widget(setting[2])
                widget.set_property('color', gtk.gdk.color_parse(value))
            elif setting[1] == FontButton:
                if value == None: value = ''
                widget = xml.get_widget(setting[2])
                widget.set_property('font-name', value)
            else:
                logging.debug('key=%s/%s' % (group, keyname))
    return

def widgets_to_config(config_prefix, config_names, config, xml):
    """Save settings into config database."""
    for group, settings in config_names.items():
        for keyname, setting in settings.items():
            if setting[0] == VALUE_STRING:
                old_value = config.get_string(group, keyname)
            elif setting[0] == VALUE_INT:
                old_value = config.get_int(group, keyname)
            elif setting[0] == VALUE_BOOL:
                old_value = config.get_bool(group, keyname)
            else:
                raise ValueError
            if setting[1] == Entry:
                widget = xml.get_widget(setting[2])
                new_value = widget.get_text()
                if setting[0] == VALUE_STRING and old_value != new_value:
                    config.set_string(group, keyname, new_value)
                elif setting[0] == VALUE_INT and old_value != string.atoi(new_value):
                    config.set_int(group, keyname, string.atoi(new_value))
            elif setting[1] == ComboBoxEntry:
                widget = xml.get_widget(setting[2])
                model = widget.get_model()
                iter = widget.get_active_iter()
                new_value = model.get_path(iter)
                if setting[0] == VALUE_STRING and old_value != new_value:
                    config.set_string(group, keyname, new_value.__str__())
                else:
                    raise Error()
            elif setting[1] == CheckButton:
                widget = xml.get_widget(setting[2])
                new_value = widget.get_property('active')
                if (old_value and not new_value) or (not old_value and new_value):                    
                    config.set_bool(group, keyname, new_value)
            elif setting[1] == RadioButton:
                new_value = 0
                for widget_name in setting[2]:
                    widget = xml.get_widget(widget_name)
                    if widget.get_property('active'):
                        break
                    new_value = new_value + 1
                if old_value != new_value:
                    config.set_int(group, keyname, new_value)
            elif setting[1] == ColorButton:
                widget = xml.get_widget(setting[2])
                color = widget.get_color()
                new_value = '#%04x%04x%04x' % (color.red,
                                               color.green,
                                               color.blue)
                if old_value != new_value:
                    config.set_string(group, keyname, new_value)
            elif setting[1] == FontButton:
                widget = xml.get_widget(setting[2])
                new_value = widget.get_property('font-name')
                if old_value != new_value:
                    config.set_string(group, keyname, new_value)
            else:
                logging.debug('key=%s/%s' % (group, keyname))
    return

def setup_checkbuttons(gladexml, defines):
    func = lambda widget, data: data.set_property('sensitive', widget.get_property('active'))
    for item in defines:
        widget = gladexml.get_widget(item[0])
        for citem in item[1]:
            cwidget = gladexml.get_widget(citem)
            widget.connect('toggled', func, cwidget)

class ConfigurationDialog(gobject.GObject):

    __gsignals__ = {
        'response' :
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),
        }

    CHECKBUTTON_DEFS = (
        ('cb_enable_disk_based_logging', ('entry_status_log_filename',
                                          'btn_status_log_filename_browse',
                                          'cb_trim_status_log_file',
                                          'spbtn_status_log_file_size')),
        ('cb_trim_status_log_file', ('spbtn_status_log_file_size',)),
        ('cb_send_keep_alive', ('cmb_keep_alive_command',
                                'spbtn_send_keep_alive_interval')),
        ('cb_stop_send_keep_alive', ('spbtn_stop_keep_alive_after',))
        )

    def __init__(self, coralftp, config=None):
        self.__gobject_init__()
        
        self.coralftp = coralftp
        if config != None:
            self.__config = config
        else:
            self.__config = coralftp.config
        
        self.__tree = get_glade_xml('configure_dialog')
        self.__tree.signal_autoconnect(self)
        self.__window = self.__tree.get_widget('configure_dialog')

        setup_checkbuttons(self.__tree, self.CHECKBUTTON_DEFS)

        config_to_widgets(CONFIG_PREFIX, CONFIG_NAMES,
                         self.__config, self.__tree)
        return
    
    def __del__(self):
        self.__window.destroy()
        return

    def on_response(self, obj, resp, *args):
        if resp in (RESPONSE_APPLY, RESPONSE_OK):
            widgets_to_config(CONFIG_PREFIX, CONFIG_NAMES,
                             self.__config, self.__tree)
        if resp in (RESPONSE_OK, RESPONSE_CANCEL):
            self.__window.set_modal(False)
            self.__window.hide()
        self.emit('response', resp)
        return

    def run(self):
        self.__window.show()
        self.__window.set_modal(True)

    def on_btn_change_color_fonts_clicked(self, obj, *args):
        def on_change_color_font_response(dlg, resp, *args):
            if resp in (RESPONSE_OK, RESPONSE_CANCEL):
                dlg.destroy()
            return

        dlg = SetColorsFontsDialog(self.__config)
        dlg.connect('response', on_change_color_font_response)
        dlg.run()
        return

gobject.type_register(ConfigurationDialog)

class SetColorsFontsDialog(gobject.GObject):

    __gsignals__ = {
        'response' :
        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),
        }

    CHECKBUTTON_DEFS = (
        ('cb_file_listing', ('fbtn_file_listing',)),
        ('cb_status', ('fbtn_status',)),
        ('cb_queue', ('fbtn_queue',))
        )

    def __init__(self, config):
        self.__gobject_init__()
        
        self.__config = config
        self.__xml = get_glade_xml('set_colors_fonts_dialog')
        self.__xml.signal_autoconnect(self)
        setup_checkbuttons(self.__xml, self.CHECKBUTTON_DEFS)
        self.__window = self.__xml.get_widget('set_colors_fonts_dialog')
        config_to_widgets(CONFIG_PREFIX, COLOR_FONT_CONFIG_NAMES,
                          self.__config, self.__xml)
        return

    def on_response(self, obj, resp, *args):
        if resp in (RESPONSE_APPLY, RESPONSE_OK):
            widgets_to_config(CONFIG_PREFIX, COLOR_FONT_CONFIG_NAMES,
                              self.__config, self.__xml)
        if resp in (RESPONSE_OK, RESPONSE_CANCEL):
            self.__window.set_modal(False)
            self.__window.hide()
        self.emit('response', resp)
        return

    def run(self):
        self.__window.show()
        self.__window.set_modal(True)
        return
    
    def destroy(self):
        self.__window.destroy()
        return

gobject.type_register(SetColorsFontsDialog)
